/**
 * 
 */

package com.gmail.hh.flickrj.sample.android.tasks;

import java.lang.ref.WeakReference;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.R;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.widget.ImageSwitcher;
import android.widget.ImageView;

import com.gmail.hh.flickrj.sample.android.data.PhotoData;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentMenu.IMenuSelectedListener;
import com.gmail.hh.flickrj.sample.android.helper.SettingsManager;
import com.gmail.hh.flickrj.sample.android.images.ImageCache;
import com.gmail.hh.flickrj.sample.android.images.ImageUtils;
import com.gmail.hh.flickrj.sample.android.images.ImageUtils.DownloadedDrawable;
import com.gmail.hh.flickrj.sample.android.tasks.LoadPhotostreamTask.IPhotostreamLoadedListener;
import com.googlecode.flickrjandroid.photos.PhotoList;

/**
 *  Load Image asynchron, invoke callback handler after loading
 *  author: helmut
 */
public class LoadImageTask extends AsyncTask<String, Integer, Bitmap> {
	
	private static final Logger logger = LoggerFactory.getLogger(LoadImageTask.class);

	// each Class using this Loader  must implement this interface
	IImageLoadedListener mCallbackLoaded;
	public interface IImageLoadedListener {
		public void onImageLoaded(PhotoData photoData);
	}

	private PhotoData photoData;
	private ImageView imageView = null;
	private WeakReference<ImageView> imgRef = null;
	private String mUrl;
	private long mDelayMSEC = 0;

	private Context mContext;
	private boolean mShowProgress;
	private ProgressDialog mProgressDialog;
	
	// two constructors possible
	public LoadImageTask(IImageLoadedListener callbackLoaded, long delayMSEC,
					PhotoData photoData, ImageView imageView, boolean showProgress, Context context) {
		this.mCallbackLoaded = callbackLoaded;
		this.mDelayMSEC = delayMSEC;
		this.photoData = photoData;
		this.imageView = imageView;
		this.imgRef = new WeakReference<ImageView>(imageView);
		this.mShowProgress = showProgress;
		this.mContext = context;
	}
	public LoadImageTask(ImageView imageView, boolean showProgress, Context context) {
		this.imageView = imageView;
		this.imgRef = new WeakReference<ImageView>(imageView);
		this.mShowProgress = showProgress;
		this.mContext = context;
	}


	@Override
	protected void onPreExecute() {
		super.onPreExecute();

		if (mShowProgress && mContext!=null) {
			mProgressDialog = ProgressDialog.show(mContext,
					"", "Loading image ..."); 
			mProgressDialog.setCanceledOnTouchOutside(true);
			mProgressDialog.setCancelable(true);
			mProgressDialog.setOnCancelListener(new OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dlg) {
					LoadImageTask.this.cancel(true);
				}
			});
		}
	}
	
	@Override
	protected Bitmap doInBackground(String... params) {
		if (mDelayMSEC>0 && mDelayMSEC<=10000) {
			try {
				Thread.sleep(mDelayMSEC);
			} catch (InterruptedException e) {
			}
		}
		mUrl = params[0];
		Bitmap image = ImageCache.getFromCache(mUrl);
		if (image != null) {
			return image;
		}
		return ImageUtils.downloadImage(mUrl);
	}

	@Override
	protected void onPostExecute(Bitmap result) {
		if (mProgressDialog != null ) {
			mProgressDialog.dismiss();
		}
		if (this.isCancelled()) {
			result = null;
			return;
		}

		ImageCache.saveToCache(this.mUrl, result);
		if (imgRef != null) {
		//	ImageView imageView = imgRef.get();
			LoadImageTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
			// Change bitmap only if this process is still associated with it
			// Or if we don't use any bitmap to task association
			// (NO_DOWNLOADED_DRAWABLE mode)
	//		if (this == bitmapDownloaderTask && bitmapDownloaderTask != null ) {
				imageView.setImageBitmap(result);
				// when imageViewMedium is loaded, then also set ImageSwitcher
				if (photoData != null && imageView==photoData.getImageViewMedium() ) { 
					// save drawable separately, because imageViewMedium is always the same address!
					// but attention of storage-consuption!!!
					photoData.setImageViewMediumDrawable( imageView.getDrawable() );
					if (photoData.getImageSwitcher()!=null  ) { 
						photoData.getImageSwitcher().setImageDrawable( imageView.getDrawable() );
					}
				}
				
	//		} 
			// invoke callback only when existing (eg. LazyAdapter is already destroyed when callback would be invoked)
			if (this.mCallbackLoaded != null ) {
				this.mCallbackLoaded.onImageLoaded(this.photoData);
			}
		}

	}

	/**
	 * This method name should be changed later, for sometimes, it will return
	 * photo id.
	 * 
	 * @return
	 */
	public String getUrl() {
		return this.mUrl;
	}

	/**
	 * @param imageView
	 *            Any imageView
	 * @return Retrieve the currently active download task (if any) associated
	 *         with this imageView. null if there is no such task.
	 */
	private LoadImageTask getBitmapDownloaderTask(ImageView imageView) {
		if (imageView != null) {
			Drawable drawable = imageView.getDrawable();
			if (drawable instanceof DownloadedDrawable) {
				DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
				return downloadedDrawable.getBitmapDownloaderTask();
			}
		}
		return null;
	}
}
